package org.oep.jmingle;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import java.util.Hashtable;
import java.io.IOException;



public class Actor {
	private String id;
	private String owner;
	private String name;
	private long lastSeen;
	private int state = 0;
	private int x = 0;
	private int y = 0;
	private Hashtable animations = new Hashtable();
	
	public static final int STAND_STILL = 0;
	public static final int WALK_UP = 1;
	public static final int WALK_DOWN = 2;
	public static final int WALK_LEFT = 3;
	public static final int WALK_RIGHT = 4;
	public static final int CUSTOM_STATE = 500;
	
	// The constructor is JMingle-specific code
	public Actor(String hash, String owner) {
		this(hash, owner, -1);
		System.out.println("2-arg constructor called");
	}
	
	public Actor(String hash, String owner, long time) {
		System.out.println("Actor() got " + time);
		this.id = hash;
		this.owner = owner;
		this.name = Utils.makeName( Utils.hexToDecimal(hash) );
		lastSeen = time;
	}
	
	public void paint(Graphics g) {
		paint(g, x, y);
	}
	
	public void paint(Graphics g, int a, int b) {
		if(currentSprite() == null)
			return;
		
		// For our purposes, just assume the sprite animation common pixel is bottom center
		
		currentSprite().setPosition(a - currentSprite().getWidth() / 2, b - currentSprite().getHeight());
		currentSprite().paint(g);
	}
	
	public void addAnimation(int state, String spriteSheet, int frameX, int frameY) {
		Image im;
		try {
			im = Image.createImage(spriteSheet);
			im = Utils.customizeMinglet(im, id);
		} catch(IOException e) {
			im = Image.createImage(frameX, frameY);
			Graphics g = im.getGraphics();
			g.setColor(0xFF0000);
			g.drawLine(0, 0, frameX, frameY);
			g.drawLine(frameX, 0, 0, frameY);
		}
		Sprite s = new Sprite(im, frameX, frameY);
		Sprite r = new Sprite(im, frameX, frameY);
		r.setTransform(Sprite.TRANS_MIRROR);
		
		putSprite(state, s);
		
		// Decide if we need to put the mirrored sprite
		if(state == Actor.WALK_LEFT && getSprite(Actor.WALK_RIGHT) == null) {
			putSprite(Actor.WALK_RIGHT, r);
		}
		else if(state == Actor.WALK_RIGHT && getSprite(Actor.WALK_LEFT) == null) {
			putSprite(Actor.WALK_LEFT, r);
		}
	}
	
	
	public void setLastSeen(long time) {
		lastSeen = time;
	}
	
	public void setPosition(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	public void setState(int state) {
		if(this.state != state) {
			// Reset current animation
			if(currentSprite() != null)
				currentSprite().setFrame(0);
			this.state = state;
		}
	}
	
	public void nextFrame() {
		if(currentSprite() != null)
			currentSprite().nextFrame();
	}
	
	public String getName() { return name; }
	public String getOwner() { return owner; }
	public String getAddress() { return id; }
	public long getLastSeen() { return lastSeen; }
	public int getX() { return x; }
	public int getY() { return y; }
	public int getState() { return state; }
	
	public int getHeight() {
		if(currentSprite() != null)
			return currentSprite().getHeight();
		else
			return 0;
	}
	
	public int getWidth() {
		if(currentSprite() != null)
			return currentSprite().getWidth();
		else
			return 0;
	}
	
	private Sprite putSprite(int s, Sprite p) {
		return (Sprite) animations.put(new Integer(s), p);
	}
	
	private Sprite getSprite(int s) {
		return (Sprite) animations.get(new Integer(s));
	}
	
	public Sprite currentSprite() {
		Sprite s = (Sprite) animations.get(new Integer(state));
		if(s == null)
			return (Sprite) animations.get(new Integer(Actor.STAND_STILL));
		else
			return s;
	}
	
	public boolean collidesWith(Actor b) {
		if(currentSprite() == null) return false;
		else if(b.currentSprite() == null) return false;
		
		return currentSprite().collidesWith(b.currentSprite(), true);
	}
	
	public String toString() {
		return getName();
	}
}
